package collections.map;

import static org.hamcrest.CoreMatchers.equalTo;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import collections.map.MyMap;
import collections.map.tree_map.MyTreeMap;

public class MyMapTestWithIntegerAndString {
	
	public static final int KEY_ZERO = 0;
	public static final int KEY_ONE = 1;
	public static final int KEY_TWO = 2;
	public static final int KEY_THREE = 3;
	public static final String VALUE_ZERO = "ZERO";
	public static final String VALUE_ONE = "ONE";
	public static final String VALUE_TWO = "TWO";
	public static final String VALUE_THREE = "THREE";
	MyMap<Integer, String> map;
	
	@Before
	public void initMap(){
		map = new MyTreeMap<>();
		map.put(KEY_ZERO, VALUE_ZERO);
		map.put(KEY_ONE, VALUE_ONE);
		map.put(KEY_TWO, VALUE_TWO);
		map.put(KEY_THREE, VALUE_THREE);
	}
	
	@Test
	public void clear_method_should_clear_not_empty_collection(){
		Assert.assertThat(map.size(), equalTo(4));
		map.clear();
		Assert.assertThat(map.size(), equalTo(0));
	}
	
	@Test
	public void containsKey_method_should_return_true_value() {
		Assert.assertThat(map.containsKey(KEY_ZERO), equalTo(true));
		Assert.assertThat(map.containsKey(KEY_ONE), equalTo(true));
		Assert.assertThat(map.containsKey(KEY_TWO), equalTo(true));
		Assert.assertThat(map.containsKey(KEY_THREE), equalTo(true));
	}
	
	@Test
	public void containsKay_method_should_return_false_value() {
		Assert.assertThat(map.containsKey(5), equalTo(false));	
	}
	
	@Test
	public void containsValue_method_should_return_true_value() {
		Assert.assertThat(map.containsValue(VALUE_ZERO), equalTo(true));
		Assert.assertThat(map.containsValue(VALUE_ONE), equalTo(true));
		Assert.assertThat(map.containsValue(VALUE_TWO), equalTo(true));
		Assert.assertThat(map.containsValue(VALUE_THREE), equalTo(true));
	}
	
	@Test
	public void containsValue_method_should_return_false_value() {
		Assert.assertThat(map.containsValue("value"), equalTo(false));
	}
	
	@Test
	public void get_method_should_return_value_mapped_by_entered_key() {
		Assert.assertThat(map.get(KEY_ZERO), equalTo(VALUE_ZERO));
		Assert.assertThat(map.get(KEY_ONE), equalTo(VALUE_ONE));
		Assert.assertThat(map.get(KEY_TWO), equalTo(VALUE_TWO));
		Assert.assertThat(map.get(KEY_THREE), equalTo(VALUE_THREE));		
	}
	
	@Test
	public void get_method_should_return_null_if_map_does_not_contains_any_value_by_current_key() {
		Assert.assertThat(map.get(5), equalTo(null));		
	}
	
	@Test
	public void isEmpty_method_should_return_false_value() {
		Assert.assertThat(map.isEmpty(), equalTo(false));	
	}
	
	@Test
	public void isEmpty_method_should_return_true_value() {
		map.clear();
		Assert.assertThat(map.isEmpty(), equalTo(true));	
	}
	
	@Test
	public void size_method_should_return_size_of_current_map() {
		Assert.assertThat(map.size(), equalTo(4));
	}
	
	@Test
	public void put_method_size_of_the_map_should_change_if_there_is_no_elements_whith_current_key() {
		Assert.assertThat(map.size(), equalTo(4));
		map.put(5, "value");
		Assert.assertThat(map.size(), equalTo(5));
	}
	
	@Test
	public void put_method_size_of_the_map_should_not_change_if_there_is_element_with_such_key() {
		Assert.assertThat(map.size(), equalTo(4));
		map.put(KEY_ZERO, "new_value");
		Assert.assertThat(map.size(), equalTo(4));
	}
	
	@Test
	public void put_method_if_there_is_no_value_with_current_key_it_added_to_the_map() {
		Assert.assertThat(map.get(5), equalTo(null));
		map.put(5, "value");
		Assert.assertThat(map.get(5), equalTo("value"));
	}
	
	@Test
	public void put_method_if_there_is_value_with_current_key_it_swaped_with_current_value() {
		Assert.assertThat(map.get(KEY_ZERO), equalTo(VALUE_ZERO));
		map.put(KEY_ZERO, "new_value");
		Assert.assertThat(map.get(KEY_ZERO), equalTo("new_value"));
	}
	
	@Test
	public void put_method_should_return_old_value_if_there_is_value_with_current_key() {
		Assert.assertThat(map.put(KEY_ZERO, "new_value"), equalTo(VALUE_ZERO));
	}
	
	@Test
	public void put_method_should_return_null_if_there_is_no_value_with_current_key() {
		Assert.assertThat(map.put(5, "new_value"), equalTo(null));
	}
	
	@Test
	public void remove_method_should_change_size_of_collection_if_element_present() {
		Assert.assertThat(map.size(), equalTo(4));
		map.remove(KEY_ZERO);
		Assert.assertThat(map.size(), equalTo(3));
	}
	
	@Test
	public void remove_method_should_not_change_size_of_collection_if_element_not_present() {
		Assert.assertThat(map.size(), equalTo(4));
		map.remove(5);
		Assert.assertThat(map.size(), equalTo(4));
	}
	
	@Test
	public void remove_method_should_return_removed_element_if_it_present_in_collection() {
		Assert.assertThat(map.remove(KEY_ZERO), equalTo(VALUE_ZERO));
	}
	
	@Test
	public void remove_method_should_return_null_if_element_dont_present_in_collection() {
		Assert.assertThat(map.remove(5), equalTo(null));
	}
	
	@Test
	public void size_method_should_return_size_of_current_collection() {
		Assert.assertThat(map.size(), equalTo(4));
	}
}